# -*- coding: UTF-8 -*-

import copy


class BaseModel(object):
    _model = None
    _emv = None
    _fields = None

    def __str__(self):
        return 'model(' + self._model + ',' + str(self.res_id) + ')'

    def __init__(self, res_id):
        self.res_id = res_id

    def read(self,  fields=None):
        return self.__class__.read(self.id, fields)

    @classmethod
    def browse(cls, ids):
        return cls(ids)

    @classmethod
    def call(cls, method, *args):
        return cls._env.rpc.call(cls._model, method, *args)

    @classmethod
    def call_kw(cls, method, *args, **kwargs):
        return cls._env.rpc.call_kw(cls._model, method, args, kwargs)

    @classmethod
    def search(cls, domain, offset=None, limit=None, order=None):
        method = 'search'
        return cls.call_kw(method, domain, offset=offset, limit=limit, order=order)

    @classmethod
    def search_read(cls, domain=None, fields=None, offset=0, limit=None, order=None, context=None):
        method = 'search_read'
        return cls.call_kw(method, domain=domain, fields=fields,
                           offset=offset, limit=limit, order=order, context=context)

    @classmethod
    def read(cls, ids, fields=None):
        method = 'read'
        return cls.call_kw(method, ids, fields=fields)

    @classmethod
    def create(cls, vals, context=None):
        method = 'create'
        return cls.call_kw(method, vals, context=context)

    @classmethod
    def write(cls, res_id, vals, context=None):
        method = 'write'
        return cls.call_kw(method, res_id, vals, context=context)

    @classmethod
    def name_get(cls, res_ids):
        method = 'name_get'
        return cls.call(method, res_ids)

    @classmethod
    def name_search(cls, domain):
        method = 'name_search'
        return cls.call(method, domain)

    @classmethod
    def unlink(cls, ids):
        method = 'unlink'
        return cls.call(method, ids)

    @classmethod
    def fields_get(cls, allfields=None, attributes=None):
        return cls.call('fields_get', allfields, attributes)

    @classmethod
    def onchange(cls, *args, **kwargs):
        return cls.call_kw('onchange', *args, **kwargs)

    @classmethod
    def _get_field_onchange(cls):

        def o2m_get(views, pfld):
            flds = {}
            for vals in views.values():
                flds.update(vals['fields'])

            flds2 = dict((pfld + '.' + fld, '1') for fld in flds)
            return flds2

        field_onchange = {}

        for fld, meta in cls._fields.items():
            field_onchange[fld] = '1'
            if meta['type'] == 'one2many':
                o2m_fields = o2m_get(meta['views'], fld)
                field_onchange.update(o2m_fields)

        return field_onchange

    @classmethod
    def get_values_for_onchange(cls, record=None, values=None):
        return cls._get_values_for_onchange(record, values)

    @classmethod
    def _get_values_for_onchange(cls, record, values):
        # todo 处理 m2o, o2m, m2m
        rec = {}
        rec.update(record)
        rec.update(values)
        return rec

    @classmethod
    def web_onchange(cls, fname, value, res_ids=None, record=None,  values=None,  context=None):
        if not res_ids:
            res_ids = []

        if not record:
            record = {}

        if not values:
            values = {}

        values2 = copy.deepcopy(values)
        values2[fname] = value

        vals_onchg = cls._get_values_for_onchange(record, values2)

        field_onchange = cls._get_field_onchange()

        result = cls.onchange(
            res_ids, vals_onchg, fname, field_onchange, context=context)

        values3 = result['value']
        values2.update(values3)

        return {'record': record, 'values': values2}

    @classmethod
    def web_onchange_new(cls, values=None, context=None):
        if not values:
            values = {}

        field_onchange = cls._get_field_onchange()

        result = cls.onchange([], values, [], field_onchange, context=context)

        value_ret = result['value']
        values_ret = copy.deepcopy(values)
        values_ret.update(value_ret)
        return {'values': values_ret}

    @classmethod
    def _get_values_for_write(cls, record, values):
        # todo 处理 只读字段
        return values

    @classmethod
    def web_commit(cls, res_id, values, record=None, context=None):
        if (res_id):
            cls.write(res_id, values, context=context)
            return res_id
        else:
            return cls.create(values, context=context)
